<?php
/**
 * Created by PhpStorm.
 * UsersF: Mloong
 * Date: 2018/12/6
 * Time: 16:26
 */

namespace app\api\service;


use app\api\model\Account;
use app\lib\enum\ScopeEnum;
use app\lib\exception\TokenException;
use Driver\Cache\Redis;
use think\Cache;
use think\facade\Config;
use think\facade\Request;

class Token
{
    # 生成令牌
    public function getToken($username)
    {
        $scope = Account::getScope($username);
        $redisValue = $this->prepareRedisValue($username,$scope);
        $token = $this->saveToCache($redisValue);
        return [
            'token' => $token,
            'scope' => $scope
        ];
    }
    # 组装权限value数组
    private function prepareRedisValue($username,$scope)
    {
        $redisValue = [];
        $redisValue['name'] = $username;
        $redisValue['scope'] = $scope;
        return $redisValue;
    }
    # 写入缓存
    private function saveToCache($redisValue)
    {
        # token
        $key = self::generateToken();
        # value
        if(!is_array($redisValue)){
            json_decode($redisValue);
        }
        $value = $redisValue;
        # 过期时间
        $expire_in = Config::get('token.token_expire_in');
        $setKey  = Redis::hMset($key, $value);
        $setTime = Redis::setKeyTime($key,$expire_in);
        if (!($setKey || $setTime)){
            throw new TokenException([
                'msg' => '服务器缓存异常',
                'errorCode' => 10005
            ]);
        }
        return $key;
    }

    # 生成令牌
    private static function generateToken()
    {
        $randChar = getRandChar(32);
        $timestamp = $_SERVER['REQUEST_TIME_FLOAT'];
        $tokenSalt = Config::get('token.token_salt');
        return md5($randChar . $timestamp . $tokenSalt);
    }

    # 获取token对应user值
    public static function getRedisTokenName()
    {
        return self::getCurrentTokenVar('name');
    }
    # 获取token对应scope值
    public static function getRedisTokenScope()
    {
        return self::getCurrentTokenVar('scope');
    }

    public static function getRedisTokenNameNotInHerder($token_str)
    {
        return self::getCurrentTokenVar('name', $token_str);
    }

    # 获取header中token获取某个值
    private static function getCurrentTokenVar($key, $token_str = null)
    {
        if($token_str == null){
            $token = Request::header('token');
        }else{
            $token = $token_str;
        }
        $vars = Redis::hget($token);
        if(!$vars){
            throw new TokenException([
                'msg' => 'Token已过期或无效'
            ]);
        }else{
            if(!is_array($vars)) {
                $vars = json_decode($vars, true);
            }
            if(array_key_exists($key,$vars)){
                return $vars[$key];
            }else{
                throw new TokenException([
                    'msg' => '尝试获取Token变量不存在'
                ]);
            }
        }
    }

}